/**
 * 电话号码本
 */
/**
 * 电话号码本属于线性结构，并且在查询和修改功能中，顺序表和链式表性能差不多
 * 但是在添加和删除联系人时，链式表的效率更高，因此采用 链式表 进行存储和操作 电话号码本
 */

 const STATUS = {
     SUCCESS: 'success',
     FAIL: 'fail',
     FATAL: 'fatal',
     RANGE_ERROR: 'range_error'
 }

 class Person {
     constructor (data) {
         this.name = data.name,
         this.phone = data.phone,
         this.address = data.address
     }
 }

 class Node {
    constructor (data, next = null) {
        this.data = data
        this.next = next
    }
 }

 class PhoneNumberBook {
     /**
      * 创建带头节点的链式表
      */
    constructor () {
        let head = new Node()
        this.data = head
    }
    /**
     * 根据用户名找到联系人的信息
     * @param {*} name 用户名
     * @returns {*} node/status 没有找到返回 range_error 找到返回 person 信息
     */
    search (name) {
        let status = STATUS.RANGE_ERROR
        let node = this.data.next
        while (node && node.data.name === name) {
            node = node.next
        }
        if (node) {
            return node
        }
        return status
    }
    /**
     * 从头部插入新的联系人信息
     * @param {*} person 联系人对象
     * @returns {*} status 返回操作状态 success or fail
     */
    insert (person) {
        let status = STATUS.FAIL
        let node = new Node()
        if (node) {
            node.data = person
            node.next = this.head.next 
            this.data.next = node
            status = STATUS.SUCCESS
        }
        return status
    }
    /**
     * 根据用户名查找到用户并删除
     * @param {*} name 
     * @returns {*} status 返回操作状态 success or fail
     */
    delete (name) {
        let status = STATUS.RANGE_ERROR
        let p = this.data.next
        let q = p // 用于暂存上一次的节点
        while (p) {
            if (node.data.name === name) {
                q.next = p.next
                status = STATUS.SUCCESS
                break
            }
            q = p
            p = p.next
        }
        return status
    }
    modify (person) {
        let status = STATUS.RANGE_ERROR
        let p = this.data.next
        while (p && p.data.name === person.name) {
            p = p.next
        }
        if (p) {
            p.name = person.name
            p.phone = person.phone
            p.address = person.address
            status = STATUS.SUCCESS
        }
        return status
    }
 }